﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;

namespace Microsoft.SqlCommunity.SQLRSS
{
    //Database "Objects" (right now tables and "reference tables") are represented with this base class.
    public class ObjectDescription : Description
    {
        // What to call this object
        public string Name { get; set; }
        // The parent object which represent a connection to the database
        public Connection DataConnection { get; set; }
        // The primary key columns in this object
        public List<ColumnDescription> IDColumns { get; protected set; }
        // What to concatenate between the key values when multi-column IDs need to be representated by a single string.
        public string IDSeparator { get; set; }
        // What columns to present to the user when the changes are viewed
        public List<ColumnDescription> DataViewColumns { get; protected set; }

        // The minimalist constructor.  Not particularly recommended.
        public ObjectDescription()
        {
            this.IDColumns = new List<ColumnDescription>();
            this.DataViewColumns = new List<ColumnDescription>();
        }

        // The preferred constructor.  objectElement contains the XML from the XML configuration file which defines this 
        // database object.
        public ObjectDescription(Connection parentDataConnection, XElement objectElement) : this()
        {
            this.Name = AttributeValueOrNull(objectElement, "Name");
            InitializeLocalMembers(objectElement, parentDataConnection);
        }

        // Given the XML from the XML configuration file that represents this database object, set the members of 
        // this object to correspond to the information in the XML configuration file.
        protected virtual void InitializeLocalMembers(XElement tableElement, Connection parentDataConnection)
        {
            this.DataConnection = parentDataConnection;

            IDColumns.Clear();

            // Grab the primary keys
            // fm is the namespace used in the XML configuration file.
            XElement idElement = tableElement.Element(fm + "ID");
            if (idElement != null)
            {
                foreach (XElement columnElement in idElement.Elements(fm + "Column"))
                {
                    this.IDColumns.Add(new ColumnDescription(columnElement));
                }
                if (idElement.Element(fm + "Separator") != null)
                    this.IDSeparator = ParseSeparator(idElement.Element(fm + "Separator").Value);
            }

            DataViewColumns.Clear();
            // Grab the columns which will be used to present information about the changed data
            XElement dataViewElement = tableElement.Element(fm + "DataView");
            if (dataViewElement != null)
            {
                foreach (XElement columnElement in dataViewElement.Elements(fm + "Column"))
                {
                    this.DataViewColumns.Add(new ColumnDescription(columnElement));
                }
                //We ignore the separator for the DataView columns by design.
            }

        }

        // Support visual names for space and tab (\space and \tab) for seperators.  Also makes sure
        // they aren't removed by the XML parser.
        protected static string ParseSeparator(string separatorEncoded)
        {
            return separatorEncoded.Replace("\\space", " ").Replace("\\tab", "  ");
        }

    }
}
